<?php

namespace RedMVC;

/**
 * Paypal class
 *  
 * @category    RedMVC
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
class Paypal{
    
    private $fields         = array();
    private $paypalUrl      = null;
    
    private $ipnData        = array();
    private $ipnResponse    = '';
    private $ipnError       = null;
    public $ipnLog          = true;
    public $ipnLogFile      = '/logs/paypalIpn.log';
    
    // fields
    public $business        = '';
    public $returnUrl       = '';
    public $cancelUrl       = '';
    public $notifyUrl       = '';
    public $cmd             = '_cart';
    public $currencyCode    = 'EUR';
    
    public function __construct($sandbox = true){    
        $this->paypalUrl = 'https://www.paypal.com/cgi-bin/webscr';
        if($sandbox){
            $this->paypalUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
        }
        
        $this->addField('rm', '2'); // return method = POST
        //$this->addField('cmd', '_xclick');
    }
    
    public function init($autoUrls = true){
    
        $rootUrl = Registry::get('RedMVC_RootUrl');
    
        if($autoUrls){
            $this->returnUrl = $rootUrl.'/paypal/success';
            $this->cancelUrl = $rootUrl.'/paypal/cancel';
            $this->notifyUrl = $rootUrl.'/paypal/ipn';
        }
    
        $this->addField('cmd', $this->cmd);
        $this->addField('business', $this->business);
		$this->addField('return', $this->returnUrl);
		$this->addField('cancel_return', $this->cancelUrl);
		$this->addField('notify_url', $this->notifyUrl);
		$this->addField('currency_code', $this->currencyCode);
		$this->addField('upload', 1);
		
		$this->ipnLogFile = APP_PATH.$this->ipnLogFile;
    }
    
    public function addField($field, $value){
        $this->fields[$field] = $value;
    }
    
    public function getFields(){
        return $this->fields;
    }
    
    public function getIpnData(){
        return $this->ipnData;
    }
    
    function submitPost(){
        $translate = Registry::get('RedMVC_Translate');
    
        $output = "<h3>".$translate->_('PAYPAL_REDIRECT_TEXT_1')."</h3>";
        $output .= "<form method=\"post\" name=\"paypal_form\"";
        $output .= "action=\"".$this->paypalUrl."\">\n";
        foreach ($this->fields as $name => $value) {
            $output .= "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n";
        }
        $output .= "<br/><br/>".$translate->_('PAYPAL_REDIRECT_TEXT_2')."";
        $output .= "...<br/><br/>\n";
        $output .= "<input type=\"submit\" value=\"".$translate->_('PAYPAL_REDIRECT_BUTTON')."\">\n";
        
        $output .= "</form>\n";
        $output .= "
        <script type=\"text/javascript\">
            window.setTimeout('submit_paypal()',1000);
            function submit_paypal(){document.forms['paypal_form'].submit();}
        </script>";
           
        return $output;
    }
   
    public function validateIpn(){    
        $urlParsed          = parse_url($this->paypalUrl);        
        $this->ipnData      = array();
        $this->ipnResponse  = '';
        //$postString         = 'cmd=_notify-validate'; // prepend ipn command
        $postString         = '';
        
        foreach($_POST as $field => $value){        
            $value = str_replace("\n", "\r\n", $value);        
            if(get_magic_quotes_gpc()){
                $value = stripslashes($value);
            }            
            $value = urlencode($value);
        
            $this->ipnData[$field] = $value;
            $postString .= $field.'='.$value.'&';
        }
        
        $postString .= "cmd=_notify-validate"; // append ipn command
        
        // open the connection to paypal
        //$fp = fsockopen($urlParsed['host'], 80, $errNum, $errStr, 30);
        $fp = fsockopen('ssl://'.$urlParsed['host'], 443, $errNum, $errStr, 30);
        
        if(!$fp){
            $this->ipnError = "fsockopen error no. $errNum: $errStr";
            $this->logIpnResults(false);
            return false;
        }
        else{
            // post the data back to paypal            
            fputs($fp, "POST $urlParsed[path] HTTP/1.0\r\n");
            //fputs($fp, "Host: $urlParsed[host]\r\n");
            fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
            fputs($fp, "Content-Length: ".strlen($postString)."\r\n\r\n");
            //fputs($fp, "Connection: close\r\n\r\n");
            fputs($fp, $postString . "\r\n\r\n");
            while(!feof($fp)){
                $this->ipnResponse .= fgets($fp, 1024);
            }
            fclose($fp);
        }
        
        if(preg_match("/VERIFIED/i", $this->ipnResponse)){
            $this->logIpnResults(true);
            return true;
        }
        else{
            $this->ipnError = 'IPN Validation Failed.';
            $this->logIpnResults(false);
            return false;
        }
    }
    
    private function logIpnResults($success){    
        if(!$this->ipnLog){
            return;
        }

        $text = '['.date('m/d/Y g:i A').'] - ';

        if($success){
            $text .= "SUCCESS!\n";
        }
        else{
            $text .= 'FAIL: '.$this->ipnError."\n";
        }
        
        // log the POST variables
        $text .= "IPN POST Vars from Paypal:\n";
        foreach ($this->ipnData as $key => $value){
            $text .= "$key=$value, ";
        }
        
        // log the response from the paypal server
        $text .= "\nIPN Response from Paypal Server:\n ".$this->ipnResponse;
        
        // write to log
        $fp = fopen($this->ipnLogFile, 'a');
        fwrite($fp, $text . "\n\n");
        fclose($fp);
    }


}